package bc

import (
	"errors"
	"fmt"
	"github.com/flipped-aurora/gin-vue-admin/server/global"
	"github.com/flipped-aurora/gin-vue-admin/server/model/bc"
	bcReq "github.com/flipped-aurora/gin-vue-admin/server/model/bc/request"
	"github.com/flipped-aurora/gin-vue-admin/server/model/common/request"
	"github.com/flipped-aurora/gin-vue-admin/server/model/common/response"
	"github.com/flipped-aurora/gin-vue-admin/server/model/system"
	"github.com/flipped-aurora/gin-vue-admin/server/service"
	"github.com/flipped-aurora/gin-vue-admin/server/utils"
	"github.com/gin-gonic/gin"
	"github.com/golang-jwt/jwt/v4"
	"go.uber.org/zap"
	"strconv"
	"sync"
	"time"
)

type BcRecordApi struct {
}

var jwtService = service.ServiceGroupApp.SystemServiceGroup.JwtService
var bcRecordService = service.ServiceGroupApp.BcServiceGroup.BcRecordService
var userService = service.ServiceGroupApp.SystemServiceGroup.UserService
var updateTimeMap = utils.NewSafeMap()

// CreateBcRecord 创建bcRecord表
// @Tags BcRecord
// @Summary 创建bcRecord表
// @Security ApiKeyAuth
// @accept application/json
// @Produce application/json
// @Param data body bc.BcRecord true "创建bcRecord表"
// @Success 200 {string} string "{"success":true,"data":{},"msg":"创建成功"}"
// @Router /bcRecord/createBcRecord [post]
func (bcRecordApi *BcRecordApi) CreateBcRecord(c *gin.Context) {
	var bcRecord bc.BcRecord
	err := c.ShouldBindJSON(&bcRecord)
	if err != nil {
		response.FailWithMessage(err.Error(), c)
		return
	}
	data, err := bcProjectService.GetBcProject(uint(bcRecord.ProjectId))
	if err != nil {
		global.GVA_LOG.Error("查询项目信息失败!", zap.Error(err))
		response.FailWithMessage("查询项目信息失败", c)
		return
	}
	bcRecord.ProjectName = data.ProjectName
	// 查询用户的code再根据code和权限去查询名字
	userData, err := userService.GetUserInfoByName(bcRecord.SysUserName)
	if err != nil {
		global.GVA_LOG.Error("查询玩家信息失败!", zap.Error(err))
		response.FailWithMessage("查询玩家信息失败", c)
		return
	}
	//userData.Balance = (userData.Balance*100 - userData.CustomerPrice*100) / 100
	bcRecord.SettleOffice = userData.SettleOffice

	//userService.SetSelfInfo(userData)

	userData, err = userService.GetUserInfoByCode(userData.SettleOffice, 8881)
	if err != nil {
		global.GVA_LOG.Error("查询玩家信息失败!", zap.Error(err))
		response.FailWithMessage("查询玩家信息失败", c)
		return
	}
	bcRecord.SuperiorsName = userData.Username
	bcRecord.UserPrice = userData.CustomerPrice
	if err := bcRecordService.CreateBcRecord(&bcRecord); err != nil {
		global.GVA_LOG.Error("创建失败!", zap.Error(err))
		response.FailWithMessage("创建失败", c)
	} else {
		response.OkWithMessage("创建成功", c)
	}
}

// DeleteBcRecord 删除bcRecord表
// @Tags BcRecord
// @Summary 删除bcRecord表
// @Security ApiKeyAuth
// @accept application/json
// @Produce application/json
// @Param data body bc.BcRecord true "删除bcRecord表"
// @Success 200 {string} string "{"success":true,"data":{},"msg":"删除成功"}"
// @Router /bcRecord/deleteBcRecord [delete]
func (bcRecordApi *BcRecordApi) DeleteBcRecord(c *gin.Context) {
	var bcRecord bc.BcRecord
	err := c.ShouldBindJSON(&bcRecord)
	if err != nil {
		response.FailWithMessage(err.Error(), c)
		return
	}
	if err := bcRecordService.DeleteBcRecord(bcRecord); err != nil {
		global.GVA_LOG.Error("删除失败!", zap.Error(err))
		response.FailWithMessage("删除失败", c)
	} else {
		response.OkWithMessage("删除成功", c)
	}
	//userData, err := userService.GetUserInfoByName(bcRecord.SysUserName)
	//if err != nil {
	//	global.GVA_LOG.Error("查询玩家信息失败!", zap.Error(err))
	//	response.FailWithMessage("查询玩家信息失败", c)
	//	return
	//}
	//userData.Balance = (userData.Balance*100 + userData.CustomerPrice*100) / 100
	//userService.SetSelfInfo(userData)
}

// DeleteBcRecordByIds 批量删除bcRecord表
// @Tags BcRecord
// @Summary 批量删除bcRecord表
// @Security ApiKeyAuth
// @accept application/json
// @Produce application/json
// @Param data body request.IdsReq true "批量删除bcRecord表"
// @Success 200 {string} string "{"success":true,"data":{},"msg":"批量删除成功"}"
// @Router /bcRecord/deleteBcRecordByIds [delete]
func (bcRecordApi *BcRecordApi) DeleteBcRecordByIds(c *gin.Context) {
	var IDS request.IdsReq
	err := c.ShouldBindJSON(&IDS)
	if err != nil {
		response.FailWithMessage(err.Error(), c)
		return
	}

	//bcRecordData, err := bcRecordService.GetBcRecordByList(IDS)
	//
	//for i := 0; i < len(bcRecordData); i++ {
	//	userData, err := userService.GetUserInfoByName(bcRecordData[i].SysUserName)
	//	if err != nil {
	//		global.GVA_LOG.Error("查询用户信息失败!", zap.Error(err))
	//		response.FailWithMessage("查询用户信息失败", c)
	//		return
	//	}
	//
	//	userData.Balance = (userData.Balance*100 + userData.CustomerPrice*100) / 100
	//	userService.SetSelfInfo(userData)
	//}

	if err := bcRecordService.DeleteBcRecordByIds(IDS); err != nil {
		global.GVA_LOG.Error("批量删除失败!", zap.Error(err))
		response.FailWithMessage("批量删除失败", c)
	} else {
		response.OkWithMessage("批量删除成功", c)
	}
}

// UpdateBcRecord 更新bcRecord表
// @Tags BcRecord
// @Summary 更新bcRecord表
// @Security ApiKeyAuth
// @accept application/json
// @Produce application/json
// @Param data body bc.BcRecord true "更新bcRecord表"
// @Success 200 {string} string "{"success":true,"data":{},"msg":"更新成功"}"
// @Router /bcRecord/updateBcRecord [put]
func (bcRecordApi *BcRecordApi) UpdateBcRecord(c *gin.Context) {
	var bcRecord bc.BcRecord
	err := c.ShouldBindJSON(&bcRecord)
	if err != nil {
		response.FailWithMessage(err.Error(), c)
		return
	}
	//rebcRecord, err := bcRecordService.GetBcRecord(bcRecord.ID)
	//if rebcRecord.SysUserName != bcRecord.SysUserName {
	//
	//	userData, err := userService.GetUserInfoByName(rebcRecord.SysUserName)
	//	if err != nil {
	//		global.GVA_LOG.Error("查询玩家信息失败!", zap.Error(err))
	//		response.FailWithMessage("查询玩家信息失败", c)
	//		return
	//	}
	//	userData.Balance = (userData.Balance*100 + userData.CustomerPrice*100) / 100
	//	userService.SetSelfInfo(userData)
	//
	//	userData, err = userService.GetUserInfoByName(bcRecord.SysUserName)
	//	if err != nil {
	//		global.GVA_LOG.Error("查询玩家信息失败!", zap.Error(err))
	//		response.FailWithMessage("查询玩家信息失败", c)
	//		return
	//	}
	//	userData.Balance = (userData.Balance*100 - userData.CustomerPrice*100) / 100
	//	userService.SetSelfInfo(userData)
	//}

	if err := bcRecordService.UpdateBcRecord(bcRecord); err != nil {
		global.GVA_LOG.Error("更新失败!", zap.Error(err))
		response.FailWithMessage("更新失败", c)
	} else {
		response.OkWithMessage("更新成功", c)
	}
}

// UpdateBcRecordCode  上传验证码
func (bcRecordApi *BcRecordApi) UpdateBcRecordCode(c *gin.Context) {
	var bcRecord bc.BcRecord
	err := c.ShouldBindQuery(&bcRecord)
	if err != nil {
		response.FailWithMessage(err.Error(), c)
		return
	}

	// 根据传进来的项目编号和手机号查询记录上传验证码
	rebcRecord, err := bcRecordService.GetBcRecordStatusByPhone(bcRecord.ProjectId, bcRecord.PhoneNumber)
	if err != nil || rebcRecord.SysUserName == "" {
		global.GVA_LOG.Error("查询失败!", zap.Error(err))
		response.FailWithMessage("查询失败", c)
		return
	}
	if bcRecord.Code == "" {
		global.GVA_LOG.Error("验证码不得为空!", zap.Error(err))
		response.FailWithMessage("验证码不得为空", c)
		return
	}

	key := rebcRecord.SysUserName + "___" + strconv.Itoa(bcRecord.ProjectId)
	syncData, ok := mapLock.Load(key)
	if !ok {
		syncData = new(sync.Mutex)
		mapLock.Store(key, syncData)
	}
	// 将a转换为sync.Mutex类型
	lock, ok := syncData.(*sync.Mutex)
	if !ok {
		global.GVA_LOG.Error("锁异常!", zap.Error(err))
		response.FailWithMessage("锁异常", c)
		return
	}
	lock.Lock()
	defer lock.Unlock()

	sysLog, err := sysLogService.GetSysLogById(uint(bcRecord.ProjectId), rebcRecord.SysUserName, time.Now().Format("2006-01-02"))
	if err != nil {
		global.GVA_LOG.Error("获取数据中心失败!", zap.Error(err))
		response.FailWithMessage("获取数据中心失败", c)
		return
	}

	if sysLog.SysUserName != "" {
		sysLog.SetCodeNum = sysLog.SetCodeNum + 1
		sysLogService.UpdateSysLog(sysLog)
	}

	// 上传验证码的时候去加数量
	rebcAgency, err := bcAgencyService.GetBcAgencyByUser(rebcRecord.SysUserName, uint(rebcRecord.ProjectId))
	if err != nil {
		global.GVA_LOG.Error("获取代理失败!", zap.Error(err))
		response.FailWithMessage("获取代理失败", c)
		return
	}
	if rebcAgency.SysUserName != "" {
		rebcAgency.Count = rebcAgency.Count + 1 //
		bcAgencyService.UpdateBcAgency(rebcAgency)
	}
	//d, _ := bcRecordService.GetBcRecordByStatus(bcRecord.ProjectId)
	//rebcRecord.PhoneNumber = d.PhoneNumber
	//rebcRecord.ID= d.ID

	rebcRecord.Code = bcRecord.Code
	rebcRecord.Status = 1
	if err := bcRecordService.UpdateBcRecord(rebcRecord); err != nil {
		global.GVA_LOG.Error("更新失败!", zap.Error(err))
		response.FailWithMessage("更新失败", c)
	} else {
		// 扣除玩家余额费用
		user, err := userService.GetUserInfoByName(rebcRecord.SysUserName)
		if err != nil {
			response.FailWithMessage(err.Error(), c)
			return
		}
		user.Balance -= user.CustomerPrice
		userService.SetSelfInfo(user)

		if err := bcTempService.DeleteBcTempByPhone(rebcRecord.PhoneNumber, user.Username); err != nil {
			global.GVA_LOG.Error("删除失败!", zap.Error(err))
			response.FailWithMessage("删除失败", c)
			return
		}
		response.OkWithMessage("更新成功", c)
	}

}

// FindBcRecord 用id查询bcRecord表
// @Tags BcRecord
// @Summary 用id查询bcRecord表
// @Security ApiKeyAuth
// @accept application/json
// @Produce application/json
// @Param data query bc.BcRecord true "用id查询bcRecord表"
// @Success 200 {string} string "{"success":true,"data":{},"msg":"查询成功"}"
// @Router /bcRecord/findBcRecord [get]
func (bcRecordApi *BcRecordApi) FindBcRecord(c *gin.Context) {
	var bcRecord bc.BcRecord
	err := c.ShouldBindQuery(&bcRecord)
	if err != nil {
		response.FailWithMessage(err.Error(), c)
		return
	}
	if rebcRecord, err := bcRecordService.GetBcRecord(bcRecord.ID); err != nil {
		global.GVA_LOG.Error("查询失败!", zap.Error(err))
		response.FailWithMessage("查询失败", c)
	} else {
		response.OkWithData(gin.H{"rebcRecord": rebcRecord}, c)
	}
}

// GetBcRecordCode 获取验证码
func (bcRecordApi *BcRecordApi) GetBcRecordCode(c *gin.Context) {
	var bcRecord bc.BcRecordReq
	err := c.ShouldBindQuery(&bcRecord)
	if err != nil {
		response.FailWithMessage(err.Error(), c)
		return
	}

	if !vaildToken(bcRecord.Token, c) {
		return
	}
	claims, err := utils.GetClaimsByToken(bcRecord.Token)
	if err != nil {
		global.GVA_LOG.Error("token解析失败!", zap.Error(err))
		response.FailWithMessage("token解析失败", c)
		return
	}

	if updateTime, ok := updateTimeMap.Get(bcRecord.PhoneNumber); !ok {
		updateTimeMap.Put(bcRecord.PhoneNumber, time.Now().Unix())
	} else {
		if updateTime+5 >= time.Now().Unix() {
			global.GVA_LOG.Error("频次太高，已拒绝!", zap.Error(err))
			response.FailWithMessage("频次太高，已拒绝", c)
			return
		} else {
			updateTimeMap.Put(bcRecord.PhoneNumber, time.Now().Unix())
		}
	}

	key := claims.Username + "___" + strconv.Itoa(bcRecord.ProjectId)
	syncData, ok := mapLock.Load(key)
	if !ok {
		syncData = new(sync.Mutex)
		mapLock.Store(key, syncData)
	}
	// 将a转换为sync.Mutex类型
	lock, ok := syncData.(*sync.Mutex)
	if !ok {
		global.GVA_LOG.Error("锁异常!", zap.Error(err))
		response.FailWithMessage("锁异常", c)
		return
	}
	lock.Lock()
	defer lock.Unlock()
	//d, _ := bcRecordService.GetBcRecordByStatus(bcRecord.ProjectId)
	//bcRecord.PhoneNumber = d.PhoneNumber
	if rebcRecord, err := bcRecordService.GetBcRecordByPhone(bcRecord.ProjectId, bcRecord.PhoneNumber); err != nil {
		global.GVA_LOG.Error("查询失败!", zap.Error(err))
		response.FailWithMessage("查询失败", c)
	} else {
		if rebcRecord.Code != "" && rebcRecord.Status == 1 {
			rebcRecord.Status = 2
			err := bcRecordService.UpdateBcRecord(rebcRecord)
			if err != nil {
				global.GVA_LOG.Error("更新状态失败!", zap.Error(err))
				response.FailWithMessage("更新状态失败", c)
				return
			}
			sysLog, err := sysLogService.GetSysLogById(uint(bcRecord.ProjectId), rebcRecord.SysUserName, time.Now().Format("2006-01-02"))
			if err != nil {
				global.GVA_LOG.Error("获取数据中心失败!", zap.Error(err))
				response.FailWithMessage("获取数据中心失败", c)
				return
			}
			if sysLog.SysUserName != "" {
				sysLog.GetCodeNum = sysLog.GetCodeNum + 1
				sysLogService.UpdateSysLog(sysLog)
			}
		}
		response.OkWithData(gin.H{"rebcRecord": rebcRecord}, c)
	}
}

func vaildToken(token string, c *gin.Context) bool {
	if token == "" {
		response.FailWithDetailed(gin.H{"reload": true}, "未登录或非法访问", c)
		return false
	}
	if jwtService.IsBlacklist(token) {
		response.FailWithDetailed(gin.H{"reload": true}, "您的帐户异地登陆或令牌失效", c)
		return false
	}

	j := utils.NewJWT()
	// parseToken 解析token包含的信息
	claims, err := j.ParseToken(token)
	if err != nil {
		if errors.Is(err, utils.TokenExpired) {
			response.FailWithDetailed(gin.H{"reload": true}, "授权已过期", c)
			return false
		}
		response.FailWithDetailed(gin.H{"reload": true}, err.Error(), c)
		return false
	}

	if claims.ExpiresAt.Unix()-time.Now().Unix() < claims.BufferTime {
		dr, _ := utils.ParseDuration(global.GVA_CONFIG.JWT.ExpiresTime)
		claims.ExpiresAt = jwt.NewNumericDate(time.Now().Add(dr))
		newToken, _ := j.CreateTokenByOldToken(token, *claims)
		newClaims, _ := j.ParseToken(newToken)
		c.Header("new-token", newToken)
		c.Header("new-expires-at", strconv.FormatInt(newClaims.ExpiresAt.Unix(), 10))
		if global.GVA_CONFIG.System.UseMultipoint {
			RedisJwtToken, err := jwtService.GetRedisJWT(newClaims.Username)
			if err != nil {
				global.GVA_LOG.Error("get redis jwt failed", zap.Error(err))
			} else { // 当之前的取成功时才进行拉黑操作
				_ = jwtService.JsonInBlacklist(system.JwtBlacklist{Jwt: RedisJwtToken})
			}
			// 无论如何都要记录当前的活跃状态
			_ = jwtService.SetRedisJWT(newToken, newClaims.Username)
		}
	}
	c.Set("claims", claims)

	return true

}

// GetBcRecordList 分页获取bcRecord表列表
// @Tags BcRecord
// @Summary 分页获取bcRecord表列表
// @Security ApiKeyAuth
// @accept application/json
// @Produce application/json
// @Param data query bcReq.BcRecordSearch true "分页获取bcRecord表列表"
// @Success 200 {string} string "{"success":true,"data":{},"msg":"获取成功"}"
// @Router /bcRecord/getBcRecordList [get]
func (bcRecordApi *BcRecordApi) GetBcRecordList(c *gin.Context) {
	var pageInfo bcReq.BcRecordSearch
	err := c.ShouldBindQuery(&pageInfo)
	if err != nil {
		response.FailWithMessage(err.Error(), c)
		return
	}

	data, err := utils.GetClaims(c)
	if err != nil {
		response.FailWithMessage("获取失败", c)
		return
	}
	list := make([]string, 0)
	switch data.AuthorityId {
	case 8881:
		data1, err := userService.GetUserListByCode(data.SettleOffice)
		if err != nil {
			response.FailWithMessage("获取失败", c)
			return
		}

		for i := 0; i < len(data1); i++ {
			list = append(list, data1[i].Username)
		}
	case 1:
		list = append(list, data.Username)
	}

	if list, total, err := bcRecordService.GetBcRecordInfoList(pageInfo, list); err != nil {
		global.GVA_LOG.Error("获取失败!", zap.Error(err))
		response.FailWithMessage("获取失败", c)
	} else {
		response.OkWithDetailed(response.PageResult{
			List:     list,
			Total:    total,
			Page:     pageInfo.Page,
			PageSize: pageInfo.PageSize,
		}, "获取成功", c)
	}
}

func (bcRecordApi *BcRecordApi) DeleteBcRecordByTime() {
	fmt.Println("开始批量删除消费记录....")
	var IDS request.IdsReq
	list, err := bcRecordService.GetBcRecordExpireList()
	if err != nil {
		global.GVA_LOG.Error("获取失败!", zap.Error(err))
		return
	}
	for b := 0; b < len(list); b++ {
		IDS.Ids = append(IDS.Ids, int(list[b].ID))
	}
	if err := bcRecordService.DeleteBcRecordByIds(IDS); err != nil {
		global.GVA_LOG.Error("批量删除消费记录失败!", zap.Error(err))
	} else {
		fmt.Println("批量删除消费记录成功")
	}
}
